<?php
/**
 * 第一步：实例化qq，并依次传入appid,回调地址,appkey
 * 第二步：调用QQAgree获取授权
 * 第三步：在回调页面->调用getOpenId方法（该方法会将获取的OpenId的值从录入$openid属性，并return）
 * 第四步：在回调页面->调用getUserInfo方法，获取用户的基本信息
 */
class QQLogin{
	private $client_id;
	private $redirect_uri;
	private $client_secret;
	public $state;
	private $openid;
	private $access_token;
	private $token_arr;

	/**
	 * @param int $client_id     申请QQ登录成功后，分配给应用的appid
	 * @param string $redirect_uri  成功授权后的回调地址
	 * @param  string $client_secret  申请qq登陆后，分配给应用的appkey
	 * @param string $state         client端的状态值。用于第三方应用防止CSRF攻击 默认状态值为test
	 */
	public function __construct($client_id,$redirect_uri,$client_secret){
		$this->client_id=$client_id;
		$this->redirect_uri=$redirect_uri;
		$this->client_secret=$client_secret;
	}
	
	/**
	 * 获取QQ授权
	 */
	public function QQAgree($state='test'){
		$client_id=$this->client_id;
		$redirect_uri=$this->redirect_uri;
		$client_secret=$this->client_secret;
		$url='https://graph.qq.com/oauth2.0/authorize?client_id='.$client_id.'&redirect_uri='.urlencode($redirect_uri).'&response_type=code&state='.$state;
		header('Location:'.$url);
	}
	
	/**
	 * 获取AccessToken的值(在回调页面使用)
	 * @return string AccessToken的值
	 */
	private function getAccessToken(){
		$uri='https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id='.$this->client_id.'&client_secret='.$this->client_secret.'&code='.$_GET['code'].'&redirect_uri='.$this->redirect_uri;
		//echo $uri.'<br/>';
		$str=$this->getUrlInfo($uri);
		//var_dump($str);				
		parse_str($str,$arr);
		$this->access_token=$arr['access_token'];
		$this->token_arr=$arr;
		$this->state=$_GET['state'];		
	}

	/**
	 * 判断以那种方式获取内容
	 * @param  string $uri 请求的地址
	 * @return string      获取的内容
	 */
	private function getUrlInfo($uri){
		//使用curl来进行模拟请求获取字符串        
		$ch = curl_init();                
		//配置选项        
		curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
		///允许请求的内容以文件流的形式返回                
		curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);//禁用https                
		curl_setopt($ch,CURLOPT_URL,$uri);//设置请求的url地址                
		$str = curl_exec($ch);//执行发送           
		if(curl_errno($ch)!=0){
			echo curl_errno($ch).'<br/>'.curl_error($ch); 
		} 
		curl_close($ch);                
		return $str;    
	}

	/**
	 * 获取用户的openid
	 * @return string 用户的openid
	 */
	public function getOpenId(){
		$this->getAccessToken();
		$uri='https://graph.qq.com/oauth2.0/me?access_token='.$this->access_token;
		//echo $uri.'<br/>';
		$str=$this->getUrlInfo($uri);
		//拼接方法
		$str=substr($str,stripos($str,'(')+1,stripos($str,')')-stripos($str,'(')-1);
		$data=json_decode($str,true);
		$this->openid=$data['openid'];
		return $data['openid'];
	}

	/**
	* 获取qq用户的信息ret 	返回码
	* @return   array
	* msg 	如果ret<0，会有相应的错误信息提示，返回数据全部用UTF-8编码。
	*nickname 	用户在QQ空间的昵称。
	*figureurl 	大小为30×30像素的QQ空间头像URL。
	*figureurl_1 	大小为50×50像素的QQ空间头像URL。
	*figureurl_2 	大小为100×100像素的QQ空间头像URL。
	*figureurl_qq_1 	大小为40×40像素的QQ头像URL。
	*figureurl_qq_2 	大小为100×100像素的QQ头像URL。需要注意，不是所有的用户都拥有QQ的100x100的头像，但40x40像素则是一定会有。
	*gender 	性别。 如果获取不到则默认返回"男"
	*is_yellow_vip 	标识用户是否为黄钻用户（0：不是；1：是）。
	*vip 	标识用户是否为黄钻用户（0：不是；1：是）
	*yellow_vip_level 	黄钻等级
	*level 	黄钻等级
	*is_yellow_year_vip 	标识是否为年费黄钻用户（0：不是； 1：是）
	*
	*/
	public function getUserInfo($outputToken=false){
		$uri='https://graph.qq.com/user/get_user_info?access_token='.$this->access_token.'&oauth_consumer_key='.$this->client_id.'&openid='.$this->openid;
		//echo $uri.'<br/>';
		$str=$this->getUrlInfo($uri);
		$info = json_decode($str,true);
		if ($outputToken) {
			$token = $this->token_arr;
			return compact('token', 'info');
		}
		return $info;
	}
}